import json

from django.conf import settings

from celery_tasks.email.tasks import send_email
from meiduo.utils.SeriCode import check_mobile_signature, generate_mobile_signature
from meiduo.utils.mixn import AuthenticateView
from users.utils import  EncodeEmailUrl
from django import http
from django.shortcuts import render, redirect
from django.contrib.auth import authenticate, login, logout, mixins
from django.contrib.auth import authenticate
from django_redis import get_redis_connection
from django.views import View
import re
from django.core.mail import send_mail

from meiduo.utils.response_code import RETCODE
from .models import User


# Create your views here.



class RegisterView(View):
    # TODO 一般JS求情都需要返回json类型数据，其他请求另说
    #  get请求性能时最好的
    # 今天测试下
    def get(self,request):
        return render(request,"register.html")
    def post(self,request):
        query_dict = request.POST
        username = query_dict.get("username")
        password = query_dict.get("password")
        password2 = query_dict.get("password2")
        mobile = query_dict.get("mobile")
        allow = query_dict.get("allow")
        sms_code = query_dict.get("sms_code")
        # 校验必传参数是否都已经传送过来
        # 对于all()来说“” [] {}都是False
        # ""不等于None
        if all([username,password,password2,mobile,allow,sms_code]) is False:
            # return JsonResponse()
            return http.HttpResponseForbidden("缺少必传参数")
        # 验证用户名格式
        if not re.match(r'^[a-zA-Z0-9_-]{5,20}$',username):
            return http.HttpResponseForbidden("请输入5-20个字符的用户")
        # 密码验证格式
        if not re.match(r'^[0-9A-Za-z]{8,20}$',password):
            return http.HttpResponseForbidden("请输入8-20个字符的密码")
        # 手机号格式验证
        if not re.match(r'^1[345789]\d{9}$',mobile):
            return http.HttpResponseForbidden("请输入正确的手机号")
        # 两次密码验证
        if password != password2:
            return http.HttpResponseForbidden("两次密码输入的不一致")
        # user = User.objects.create(
        #     username=username
        # )
        # user.set_password(password)
        # TODO 利用django自带方法直接创建用户对象
        try :
            User.objects.get(mobile=mobile)
            return http.HttpResponseForbidden("手机号码已经注册")
        except:
            user = User.objects.create_user(username=username, password=password, mobile=mobile)
            login(request, user)
            next = request.GET.get('next')
            # 返回响应
            response = redirect(next or '/')  # 创建响应对象
            # 给cookie中设置username
            response.set_cookie('username', username,
                                max_age=settings.SESSION_COOKIE_AGE)
            return response



class UsernameCountView(View):
    def get(self,request,username):
        cont = User.objects.filter(username=username).count()
        data = {"count":cont}
        return http.JsonResponse(data)

class MobileCountView(View):
    def get(self,request,mobile):
        count=User.objects.filter(mobile=mobile).count()
        data={"count":count}
        return http.JsonResponse(data=data)


class LoginView(View):
    def get(self,request):
       return render(request,"login.html")

    def post(self,request):
        # 1.获取手机号，密码。
        query_dict = request.POST
        password = query_dict.get("password")
        username = query_dict.get("username")
        remembered =query_dict.get("query_dict")
        # 2.返回登录成功的页面
        # Todo 用户认证，但是只支持用户名密码登录，多登陆需要修改authenticate方法
        user = authenticate(username=username, password=password)
        # 3.看是否需要状态保持
        if user is  None:
            return render(request, 'login.html', {'account_errmsg': '用户名或密码错误'})

        login(request,user) # 登录成功则状态保持
        if remembered is not None:
            request.session.set_expiry(0)
        next = request.GET.get('next')
        # 返回响应
        response = redirect(next or '/')  # 创建响应对象
        # 给cookie中设置username
        response.set_cookie('username', username, max_age=(None if remembered is None else settings.SESSION_COOKIE_AGE))
        return response


class LogoutView(View):
    def get(self,request):
        logout(request)
        # 退出登录,同事需要吧设置在客户端的cookie给去除掉
        response = redirect('/login/')
        response.delete_cookie("username")
        return response
class InfoView(mixins.LoginRequiredMixin,View):
    def get(self,request):
        return render(request,"user_center_info.html")


class EamilView(AuthenticateView):
    def put(self,request):
        # 获取邮件

        body_data = request.body
        email = json.loads(body_data.decode()).get("email")
        # 校验邮件
        if not re.match(r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$',email):
            return http.HttpResponseForbidden("邮件格式错误")
        # 数据入库保存
        """ 
        subject, message, from_email, recipient_list,
              fail_silently=False, auth_user=None, auth_password=None,
              connection=None, html_message=None
        """
        """
        EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'  # 指定邮件后端
        EMAIL_HOST = 'smtp.163.com'  # 发邮件主机
        EMAIL_PORT = 25  # 发邮件端口
        EMAIL_HOST_USER = 'itcast99@163.com'  # 授权的邮箱
        EMAIL_HOST_PASSWORD = 'python99'  # 邮箱授权时获得的密码，非注册登录密码
        EMAIL_FROM = '美多商城<itcast99@163.com>'  # 发件人抬头
       
        """
        user = request.user
        user.email = email
        user.save()

        url = EncodeEmailUrl(user)
        send_email.delay(email,url)
        # 返回


        return http.JsonResponse({"code":RETCODE.OK})


class PassWordView(AuthenticateView):
    def get(self,request):
        return render(request,'user_center_pass.html')
    def post(self, request):
        """实现修改密码逻辑"""

        # 接收参数
        old_password = request.POST.get('old_pwd')
        password = request.POST.get('new_pwd')
        password2 = request.POST.get('new_cpwd')

        # 校验
        if all([old_password, password, password2]) is False:
            return http.HttpResponseForbidden("缺少必传参数")

        user = request.user
        if user.check_password(old_password) is False:
            return render(request, 'user_center_pass.html', {'origin_pwd_errmsg': '原始密码错误'})

        if not re.match(r'^[0-9A-Za-z]{8,20}$', password):
            return http.HttpResponseForbidden('密码最少8位，最长20位')
        if password != password2:
            return http.HttpResponseForbidden('两次输入的密码不一致')

        # 修改密码
        user.set_password(password)
        user.save()

        # 响应重定向到登录界面
        logout(request)
        response = redirect('/login/')
        response.delete_cookie('username')
from django.views.generic.base import View
from django_redis import get_redis_connection
from django import http
import re
import random
import json
from django.conf import settings




class Find_passwordView(View):
    """找回mima首页"""

    def get(self,request):

        return render(request,'find_password.html')


class Get_Token(View):
    """获取token,限定修改时间"""
    def get(self,request,username):

        username = username

        request_dict = request.GET
        user_imagecode = request_dict.get('text')
        uuid = request_dict.get('image_code_id')
        print('user_imagecode',user_imagecode)
        redis_conn = get_redis_connection('SMSCODE')
        try:
            redis_code = redis_conn.get(uuid).decode()
            redis_conn.delete(uuid) # 保证只能用一次.decode()
        except:
            return http.JsonResponse({},status=400,errmsg="验证码超时")

        if redis_code is None:
            return http.JsonResponse({},status=400)

        if redis_code.lower() != user_imagecode.lower():
            return http.JsonResponse({},status=400)


        if not re.match(r'^[a-zA-Z0-9_-]{5,20}$', username):
            if not re.match(r'^1[3-9]\d{9}',username):
                return http.JsonResponse({},status=404)
        try:
            user = User.objects.get(username=username)
        except:
            return http.JsonResponse({},status=404)

        mobile = user.mobile

        mobile_signature = generate_mobile_signature({"mobile":mobile})

        data = {'access_token':mobile_signature,'mobile':mobile}

        response = http.JsonResponse(data)

        response.set_cookie('access_token',mobile_signature,RETCODE.CODETIME)
        return response


class Send_smscode(View):
    """发送短信"""

    def get(self,request):

        mobile_signature = request.GET.get('access_token')
        if mobile_signature is None:
            data={'message':'缺少必要参数'}
            return http.JsonResponse(data,status=404)
        try:
            mobile_signature2 = request.COOKIES['access_token']
        except:
            data={'message':'操作超时'}
            return http.JsonResponse(data,status=404)

        if mobile_signature != mobile_signature2:  # 确保请求和cookie中的一样
            data = {'message': '错误请求'}
            return http.JsonResponse(data,status=404)

        sms_code = '%06d' %random.randint(0,999999)
        print(sms_code)

        mobile_dict = check_mobile_signature(mobile_signature)
        mobile=mobile_dict.get("mobile")
        # send_sms_code.delay(mobile,sms_code)

        data = {'message': '短信发送成功'}
        request.session[mobile] = sms_code
        response = http.JsonResponse(data)

        return response


class Check_SMScode(View):
    """验证短信"""

    def get(self,request,username):

        sms_code = request.GET.get('sms_code')

        try:
            mobile_signature = request.COOKIES['access_token']
        except:
            return http.JsonResponse({'message': '操作超时'},status=400)

        mobile = check_mobile_signature(mobile_signature).get('mobile')
        if mobile is None:
            return http.JsonResponse({'message': '操作超时'},status=400)

        try:
            session_smscode = request.session[mobile]
        except:
            return http.JsonResponse({'message':'短信验证码已过期'},status=400)

        del request.session[mobile]
        if sms_code != session_smscode:
            return http.JsonResponse({},status=400)

        try:
            user = User.objects.get(username=username,mobile=mobile)
        except:
            return http.JsonResponse({}, status=404)

        data = {
            'user_id':user.id,
            'access_token': mobile_signature,
        }
        response = http.JsonResponse(data)

        return response


class SetPassword(View):
    """修改密码"""
    def post(self,request,user_id):

        id = user_id
        json_list = request.body.decode()
        post_list = json.loads(json_list)

        password = post_list.get('password')
        password2 = post_list.get('password2')
        mobile_signature = post_list.get('access_token')

        if all([user_id,password,password2,mobile_signature]) is False:
            data = {'message':RETCODE.PWDERR,}
            response = http.JsonResponse(data,status=400)
            return response

        if not re.match(r'^[a-zA-Z0-9]{8,20}$', password):
            data = {'message': RETCODE.PWDERR, }
            response = http.JsonResponse(data,status=400)
            return response
        if password != password2:
            data = {'message': RETCODE.CPWDERR , }
            response = http.JsonResponse(data,status=400)
            return response

        try:
            mobile_signature2 = request.COOKIES['access_token']
        except:
            data = {'message': RETCODE.PWDERR, }
            response = http.JsonResponse(data,status=400)
            return response

        if mobile_signature != mobile_signature2:
            data = {'message': RETCODE.PWDERR, }
            response = http.JsonResponse(data,status=400)
            return response

        mobile = check_mobile_signature(mobile_signature).get('mobile')
        if mobile is None:
            data = {'message': RETCODE.PWDERR, }
            response = http.JsonResponse(data,status=400)
            return response

        try:
            user = User.objects.get(id=id,mobile=mobile)
        except:
            data = {'message': RETCODE.PWDERR, }
            response = http.JsonResponse(data,status=400)
            return response
        user.set_password(password)
        user.save()

        response = http.JsonResponse({})

        return response